package com.sxhuayuan.parking.service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.sxhuayuan.parking.compenent.Page;
import com.sxhuayuan.parking.compenent.Pageable;
import com.sxhuayuan.parking.compenent.domain.KeyValue;
import com.sxhuayuan.parking.config.PayMode;
import com.sxhuayuan.parking.config.PayStatus;
import com.sxhuayuan.parking.config.Platform;
import com.sxhuayuan.parking.dto.OrderListDTO;
import com.sxhuayuan.parking.dto.ParkFeeCacheBean;
import com.sxhuayuan.parking.dto.SumDTO;
import com.sxhuayuan.parking.entity.*;

public interface OrderService extends BaseService<Order, Long> {

	/**
	 * 删除停车场订单
	 */
	void deleteByParkingLotId(Long id);

	// /**
	// * 创建订单
	// */
	// @Deprecated
	// Order create(OriginalParkingInfo parkingInfo, ParkingLot lot, ParkChannel
	// exit, String carPlate, Member member, BigDecimal money, String pluginId,
	// Platform platform, PayMode payMode,
	// String ip, String remark);

	/**
	 * 创建订单。后面所以订单都使用ParkingIn记录创建。第三方车场系统的记录也会保存到parkingInOut中，即ParkingInOut对象代替掉原来的OriginalParkingInfo
	 */
	Order create(ParkingIn in, ParkFeeCacheBean parkFee, Member member, Platform platform, PayMode payMode, Order.Method method, String ip, String remark);

	/**
	 * 下单前更新订单
	 * 
	 * @param order
	 * @param platform
	 * @param payMode
	 * @param member
	 * @param exitId
	 *            TODO
	 * @param remark
	 */
	void update(Order order, Platform platform, PayMode payMode, Member member, Long exitId, String remark);

	/**
	 * 根据订单标号查询订单
	 */
	Order findBySn(String orderSn);
	
	/** 根据车场单号查 */
	Order findByLotOrderNo(String lotOrderNo);

	/** 根据保存的进场时间查 */
	List<Order> findByEntertimeAndCarPlate(Date entertime, String carPlate);

	/** 查询缴费历史 */
	List<Order> findPaidListByUniqueId(Long uniqueId);

	/** 分页条件查询 */
	Page<Order> findPage(OrderListDTO orderPage, Agent agent);

	/** 根据车场查询订单 */
	Page<Order> findPageByParkingLot(OrderListDTO orderPage, ParkingLot parkingLot);

	Page<Order> findPageByAgent(Agent agent, OrderListDTO orderPage);

	/** 根据page条件查询金额 */
	Map<String, Object> findCount(OrderListDTO orderPage, Agent agent);

	/** 根据page条件查询金额 车场用户 */
	Map<String, Object> countByPageAndParkingLot(OrderListDTO orderPage, ParkingLot parkingLot);

	/** 根据车场某出口订单数 */
	Long findCountByExit(Long id);

	/**
	 * 订单支付处理
	 * 
	 * @param order
	 */
	void paySuccess(Order order, String huabeiOrderSn);

	/**
	 * 订单完成状态通知第3方成功
	 * 
	 * @param order
	 */
	void notifySuccess(Order order);

	/************ **************/

	@Deprecated
	/** 根据华贝订单号查询 */
	Order findByTradeNo(String tradeNo);

	void saveList(List<Order> orders);

	/**
	 * 删除超时未支付订单，3天前吧，避免因支付系统回调失败导致支付状态未更新的订单被删掉
	 */
	void clearTimeoutOrders(String endTime);

	/** 根据page条件查询金额 */
	BigDecimal findCountMoney(OrderListDTO orderPage, Agent agent);

	/**
	 * 根据时间、车场、代理查询订单统计
	 * 
	 * @param formatType
	 *            时间格式化类型
	 * @param startTime
	 *            起始时间
	 * @param endTime
	 *            结束时间
	 * @param sn
	 *            车场编号
	 * @param agent
	 *            代理
	 * @return 订单统计
	 */
	List<Map<String, Object>> findCountByDateTime(String formatType, String startTime, String endTime, String sn, Agent agent);

	/** 根据时间查询所有停车场订单统计 */
	List<Map<String, Object>> findParkingLotByDateTime(String startTime, String endTime, Agent agent);

	/** 根据时间查询订单数量、金额统计 */
	SumDTO countByDataTime(Date startTime, Date endTime, Agent agent);

	/** 根据停车场查询订单数量、金额统计 */
	SumDTO countByParkingLot(Date startTime, Date endTime, ParkingLotUser parkingLotUser);

	/** 根据代理查询某一天的交易总流水 */
	ProfitStatistics countProfitStatisticsByAgent(Agent agent, LocalDate date);

	/** 根据车场查询前一天订单流水 */
	BigDecimal[] countByParkingLotAndPaytime(ParkingLot parkingLot, LocalDate date);

	/** 通过条件筛选，查询结果，用于报表导出 */
	List<Order> findByDownloadReport(ParkingLotUser current, String plateNum, PayStatus payStatus, Platform platform, Date beginTime, Date endTime);
	
	List<Order> findByUniqueId(Long uniqueId);
	
	int countByUniqueId(Long uniqueId);

	/** 业务员订单的分页查询 */
	Page<Order> findPage(Pageable pageable, Salesman salesman);

	/** 分页查询统计 */
    JSONObject statistical(Pageable pageable, Salesman salesman);

    /** 车场用户分页查询订单 */
    Page<Order> findPage(Pageable pageable, ParkingLotUser parkingLotUser);

    /** 车场用户分页查询订单统计 */
	JSONObject statistical(Pageable pageable, ParkingLotUser parkingLotUser);

	/** 根据时间和车场查账用户查询订单统计 */
	List<Map<String, Object>> countByDateTimeAndParkingLotUser(String startTime, String endTime, ParkingLotUser current);

	/** 通过订单编号和用户查询符合开具发票的订单 */
	List<Order> findByOrderSnAndMemberIdAndParkingLot(List<String> ids, Member current, ParkingLot parkingLot);

	/** 通过用户查找能开发票订单对应的车场列表 */
	List<KeyValue> findParkingListByMember(Member member);

	/** 通过用户与车场分页查询可以开发票的订单 */
	Page<Order> findPage(Pageable pageable, Member member, ParkingLot parkingLot);
}
